import logging
from wombat import WombatActionPlugin
from models import WombatQuery, Account
from google.appengine.ext import db
from yengine import controller
import json
import datetime
from xmlobjects.xmlobject import XMLObject
import os


class ScopeManager(WombatActionPlugin):
  def get(self):
    try:
      if self.request.get('delete_scope'):
        account = db.get(self.request.get('delete_scope'))
        if account and account.has_scope(self.request_handler.active_account()):
          self.entity.remove_scope(account)
          self.entity.put()
          if not account.is_in_use():
            account.hide()
            if '.' in os.environ['HTTP_HOST']:
              account.queue_method_calls('make_search_index')

      template_values = {}
      template_values['url'] = self.request.url
      html = ''
      html += '<div id="scope_manager">'
      html += '<table cellpadding="5" cellspacing="5">'
      html += '<thead>'
      html += '<tr>'
      html += '<th><input id="scope_manager_select_all" type="checkbox" name="scope_manager_select_all" /></th>'
      html += '<th>Name</th>'
      html += '<th>ID</th>'
      html += '<th>External ID</th>'
      html += '<th>Type</th>'
      html += '<th>Service Provider</th>'
      html += '<th></th>'
      html += '</tr>'
      html += '</thead>'
      html += '<tbody>'
      scope = self.entity.get_scope(True, False)
      scope = map(db.get, scope)
      scope = sorted(scope, key=str)
      for account in scope:
        html += '<tr>'
        if account.has_scope(self.request_handler.active_account()):
          html += '<td><input class="scope_manager_select" type="checkbox" name="account" value="%s" /></td>' % account.key()
        else:
          html += '<td>&nbsp;</td>'
        html += '<td><a href="%s">%s</a></td>' % (account.uri, account)
        html += '<td title="%s"><img data-clipboard="%s" alt="Key" src="/images/key_alt.png" style="height: 1.5ex;" /> %s</td>' % (account.key(), account.key(), account.key().id_or_name())
        html += '<td>%s</td>' % (account.external_id or '')
        html += '<td>%s</td>' % (account.service_account and 'Partner' or 'Regular')
        service_provider_details = ''
        if account.service_provider:
          service_provider_details = '<a href="%s">%s</a>' % (account.get_cached_reference_property('service_provider', 'uri'), account.get_cached_reference_property('service_provider', 'name'))
        html += '<td>%s</td>' % service_provider_details
        if account.has_scope(self.request_handler.active_account()):
          html += '<td class="delete" data-key="%s">x</td>' % account.key()
        else:
          html += '<td>&nbsp;</td>'
        html += '</tr>'
      html += '</tbody>'
      html += '</table>'
      html += '<button id="scope_manager_delete_selected">Delete Selected</button>'
      html += '<br /><br />'
      html += '<form id="scope_manager_add" action="%(url)s" method="post">'
      html += '<select name="new_scope">'
      for account in WombatQuery(Account, _list_projection=True).scope(self.request_handler.active_account()).order('name'):
        if not account.key() in self.entity.get_scope(False, False) and not account.is_hidden():
          html += '<option value="%s">%s</option>' % (account.key(), account)
      html += '</select>'
      html += '<input type="submit" value="Add" />'
      html += '</form>'
      html += '</div>'

      self.response.out.write(html % template_values)
      self.response.headers['Content-Type'] = 'text/html'
    except Exception, e:
      logging.error('Failed to scope manager for '+str(self.entity)+' ['+str(self.entity.key())+']')
      logging.exception(e)
      self.response.out.write('We could not process the request.')
      self.response.headers['Content-Type'] = 'text/plain'

  def post(self):
    account = db.get(self.request.get('new_scope'))
    if account and account.has_scope(self.request_handler.active_account()):
      self.entity.add_scope(account)
      self.entity.put()


class PropertyNullifier(WombatActionPlugin):

  @controller
  def post(self):
    property_name = self.request.get('property')
    logging.debug('Nullifying %s of %s' % (property_name, repr(self.entity)))
    setattr(self.entity, property_name, None)
    logging.info('Nullified %s of %s' % (property_name, repr(self.entity)))
    self.entity.put()
    logging.debug('Put %s' % (repr(self.entity)))
    self.response.out.write('Property %s of %s nullified' % (property_name, self.entity))


class JSONViewer(WombatActionPlugin):

  @controller
  def get(self):
    properties = {'__key__': str(self.entity.key())}

    for key in self.entity.properties():
      if key in self.entity.strong_exclude and not self.request.get('view') == 'complete':
        continue
      if key in ['scope']:
        continue

      if isinstance(getattr(self.entity.__class__, key), (db.ReferenceProperty)):
        properties[key] = unicode(self.entity.get_reference_property_key(key))
      elif key[:1] == '_' and hasattr(self.entity, key[1:]):
        a_key = key[1:]
        properties[a_key] = getattr(self.entity, a_key)
      else:
        properties[key] = getattr(self.entity, key)

    for key, value in properties.iteritems():
      if isinstance(value, (datetime.time, datetime.datetime, datetime.date, XMLObject)):
        properties[key] = unicode(value)

    logging.info(properties)
    as_json = json.dumps(properties)
    self.response.out.write(as_json)

